from dataclasses import dataclass, field
from typing import List, Optional, Dict, Any
from datetime import datetime
from dataclasses import dataclass, field
import json
import hashlib
import uuid


@dataclass
class Category:
    """分类数据模型"""
    id: str
    name: str
    description: Optional[str] = None
    color: Optional[str] = None
    enabled: bool = True
    created_at: str = field(default_factory=lambda: datetime.now().isoformat())
    updated_at: str = field(default_factory=lambda: datetime.now().isoformat())
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典格式"""
        return {
            'id': self.id,
            'name': self.name,
            'description': self.description,
            'color': self.color,
            'enabled': self.enabled,
            'created_at': self.created_at,
            'updated_at': self.updated_at
        }
    
    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> 'Category':
        """从字典创建分类对象"""
        return cls(
            id=data['id'],
            name=data['name'],
            description=data.get('description'),
            color=data.get('color'),
            enabled=data.get('enabled', True),
            created_at=data.get('created_at', datetime.now().isoformat()),
            updated_at=data.get('updated_at', datetime.now().isoformat())
        )


@dataclass
class PromptItem:
    """提示词数据模型"""
    id: str
    title: str
    content: str
    tags: List[str] = field(default_factory=list)
    enabled: bool = True
    category_id: str = "default"
    notion_page_id: Optional[str] = None
    variables: Optional[List[str]] = field(default=None, init=False)
    
    def __post_init__(self):
        """初始化后处理，提取变量"""
        self.variables = self.extract_variables()
    
    def extract_variables(self) -> List[str]:
        """从内容中提取变量"""
        import re
        pattern = r'\{\{([^{}]+)\}\}'
        matches = re.findall(pattern, self.content)
        return list(set(matches))  # 去重
    
    def replace_variables(self, variable_values: Dict[str, str]) -> str:
        """替换变量值"""
        import re
        pattern = r'\{\{([^{}]+)\}\}'
        
        def replace_func(match):
            var_name = match.group(1)
            return variable_values.get(var_name, match.group(0))
        
        return re.sub(pattern, replace_func, self.content)
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典格式"""
        return {
            'id': self.id,
            'title': self.title,
            'content': self.content,
            'tags': self.tags,
            'enabled': self.enabled,
            'category_id': self.category_id,
            'notion_page_id': self.notion_page_id
        }
    
    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> 'PromptItem':
        """从字典创建提示词对象"""
        return cls(
            id=data['id'],
            title=data['title'],
            content=data['content'],
            tags=data.get('tags', []),
            enabled=data.get('enabled', True),
            category_id=data.get('category_id', 'default'),
            notion_page_id=data.get('notion_page_id')
        )


class PromptUtils:
    """提示词工具类"""
    
    @staticmethod
    def generate_prompt_id(title: str, content: str, tags: Optional[List[str]] = None) -> str:
        """生成提示词唯一ID"""
        unique_string = f"{title.strip()}::{content.strip()}"
        if tags:
            sorted_tags = sorted(tags)
            unique_string += f"::{','.join(sorted_tags)}"
        
        # 使用SHA256生成哈希
        hash_obj = hashlib.sha256(unique_string.encode('utf-8'))
        hash_hex = hash_obj.hexdigest()[:16]  # 取前16位
        
        # 添加前缀p确保以字母开头
        return f"p{hash_hex}"
    
    @staticmethod
    def generate_category_id() -> str:
        """生成分类唯一ID"""
        return str(uuid.uuid4())


# 默认分类配置
DEFAULT_CATEGORIES = [
    Category(
        id="default",
        name="默认",
        description="系统默认分类，用于存放未分类的提示词",
        color="#6366f1"
    ),
    Category(
        id="programming",
        name="编程开发",
        description="编程、代码相关的提示词",
        color="#10b981"
    ),
    Category(
        id="painting",
        name="绘画",
        description="绘画相关的提示词",
        color="#f59e0b"
    )
]

# 默认提示词样例
DEFAULT_PROMPTS = [
    PromptItem(
        id="default-ghibli",
        title="吉卜力风格",
        content="将图片转换为吉卜力风格",
        tags=["画图", "吉卜力"],
        category_id="painting"
    ),
    PromptItem(
        id="default-code-explain",
        title="代码解释",
        content="请解释以下代码的功能和工作原理：\n\n",
        tags=["编程"],
        category_id="programming"
    ),
    PromptItem(
        id="default-role-template",
        title="开发角色",
        content="你现在是一个{{角色}}，有着{{年限}}年的开发经验，擅长{{技能}}。",
        tags=["编程", "变量"],
        category_id="programming"
    )
]